~3 min read • Updated Oct 29, 2025
1. error.js — Handling Runtime Errors
The error.js file acts as a React Error Boundary. When an error occurs in a route segment, it displays a fallback UI.
'use client'
export default function Error({ error, reset }) {
useEffect(() => {
console.error(error)
}, [error])
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
)
}Key Features:
- error.message: Debug message
- error.digest: Unique hash for server-side logs
- reset(): Attempts to re-render the segment
2. global-error.tsx — Handling Root-Level Errors
Use global-error.tsx to handle errors in the root layout. This file must include html and body tags.
'use client'
export default function GlobalError({ error, reset }) {
return (
<html>
<body>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
)
}3. GracefullyDegradingErrorBoundary — Elegant Recovery
This component captures the current HTML before an error and re-renders it without hydration, showing a persistent notification bar.
if (this.state.hasError) {
return (
<>
<div dangerouslySetInnerHTML={{ __html: cachedHTML }} />
<div className="notification">An error occurred</div>
</>
)
}4. forbidden.js — Displaying a 403 Page
The forbidden.js file renders a custom UI when the forbidden() function is triggered during authentication.
export default function Forbidden() {
return (
<div>
<h2>Forbidden</h2>
<p>You are not authorized to access this resource.</p>
<Link href="/">Return Home</Link>
</div>
)
}5. instrumentation.js — Observability and Error Tracking
The instrumentation.ts file lets you track server performance and report errors to external services.
export function register() {
registerOTel('next-app')
}
export const onRequestError = async (err, request, context) => {
await fetch('https://.../report-error', {
method: 'POST',
body: JSON.stringify({ message: err.message, request, context }),
headers: { 'Content-Type': 'application/json' },
})
}Parameters:
- error.digest: Unique error ID
- request: Path, method, headers
- context: Router type, route type, render source, revalidation reason
6. Targeting Runtime
To run different logic in Node.js or Edge:
if (process.env.NEXT_RUNTIME === 'edge') {
return require('./register.edge')
} else {
return require('./register.node')
}Conclusion
Next.js provides robust tools like error.js, forbidden.js, and instrumentation.js to handle errors, control access, and monitor performance. These features help developers build resilient, secure, and user-friendly applications.
Written & researched by Dr. Shahin Siami